/** DOM变化事件 */
import eeui from '../ee-vuex'

function isMobile() {
  return !!navigator.userAgent.match(/(phone|pad|pod|iPhone|iPod|ios|iPad|Android|Mobile|BlackBerry|IEMobile|MQQBrowser|JUC|Fennec|wOSBrowser|BrowserNG|WebOS|Symbian|Windows Phone)/i);
}

function resize() {
  // 主要是F12切换PC和手机
  eeui.mb = isMobile();

  setTimeout(() => {
    const width = document.body.clientWidth;
    const height = window.innerHeight - 1;
    const id = "ee-ui-viewport";
    
    eeui.width = width;
    eeui.height = height;
    // 有时需要DOM撑满屏幕，100vh在QQ浏览器底部有工具栏时会出现滚动条
    // window.innerHeight将不包含工具栏
    var root = document.querySelector("#" + id) || document.head.appendChild(document.createElement("style"));
    root.id = id;
    root.innerHTML = `:root {
  --width: ${width}px;
  --height: ${height}px;
}`;

    const item = _onwidth.find(i => i.e === window);
    if (item)
      for (const action of item.actions)
        action(window, eeui.width, eeui.height);
  }, 200)
}

resize();
addEventListener('resize', resize);

/**
 * @callback resize
 * @param {HTMLElement} dom - 尺寸变化的DOM元素
 * @param {number} width - DOM元素的宽
 * @param {number} height - DOM元素的高
 */

/**
 * @typedef {object} onresize
 * @property {HTMLElement} e - 侦听的DOM元素
 * @property {resize[]} actions - 尺寸变化时的回调函数
 * @property {ResizeObserver} watcher - 侦听DOM元素尺寸变化的观察者，window为空
 */

/** 已经侦听的DOM元素宽变化事件
 * @type {onresize[]} */
const _onwidth = [];

/** 停止一个侦听
 * @param {number} i - 要关闭的侦听
 */
function stop(i) {
  const value = _onwidth[i];
  if (!value)
    return;
  if (value.watcher) {
    value.watcher.unobserve(value.e);
    value.watcher.disconnect();
  }
  _onwidth.splice(i, 1);
}

/** 侦听DOM元素宽度发生变化
 * @param {resize} func - 事件回调，传空并且是取消侦听则取消全部侦听
 * @param {boolean} [cancel] - 取消侦听
 * @param {HTMLElement} [dom=window] - 要侦听宽度变化的DOM元素，默认是window
 */
export function onwidth(func, cancel, dom) {
  // 尝试清空那些DOM元素可能已经不存在的侦听以释放内存
  for (let i = _onwidth.length - 1; i >= 0; i--)
    if (!_onwidth[i].e.parentElement)
      stop(i);
  if (!dom)
    dom = window;
  if (cancel) {
    if (func) {
      const index = _onwidth.findIndex(i => i.e === dom);
      const t = _onwidth[index];
      if (t) {
        for (let i = t.length - 1; i >= 0; i--)
          if (t[i] == func)
            t = t.splice(i, 1);
        if (t.length == 0)
          stop(index);
      }
    } else {
      // 没有func清除所有的回调
      stop(_onwidth.findIndex(i => i.e === dom));
    }
  } else {
    if (!func) return;
    let item = _onwidth.find(i => i.e === dom);
    if (!item) {
      item = {
        e: dom,
        actions: [],
        watcher: dom === window ? undefined :
          new ResizeObserver((entries) => {
            requestAnimationFrame(() => {
              for (const action of item.actions)
                action(dom, entries[0].contentRect.width, entries[0].contentRect.height);
            })
          })
      };
      _onwidth.push(item);
    }
    item.actions.push(func);
  }
}